package xjay.ai.emotionalsupport.tools;

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;



@Slf4j
@Component
public class TarotCardTool {
    // 塔罗牌大阿卡纳牌名映射
    private static final Map<Integer, String> MAJOR_ARCANA = Map.ofEntries(
        Map.entry(0, "愚者 (The Fool)"),
        Map.entry(1, "魔术师 (The Magician)"),
        Map.entry(2, "女祭司 (The High Priestess)"),
        Map.entry(3, "皇后 (The Empress)"),
        Map.entry(4, "皇帝 (The Emperor)"),
        Map.entry(5, "教皇 (The Hierophant)"),
        Map.entry(6, "恋人 (The Lovers)"),
        Map.entry(7, "战车 (The Chariot)"),
        Map.entry(8, "力量 (Strength)"),
        Map.entry(9, "隐士 (The Hermit)"),
        Map.entry(10, "命运之轮 (Wheel of Fortune)"),
        Map.entry(11, "正义 (Justice)"),
        Map.entry(12, "倒吊人 (The Hanged Man)"),
        Map.entry(13, "死神 (Death)"),
        Map.entry(14, "节制 (Temperance)"),
        Map.entry(15, "恶魔 (The Devil)"),
        Map.entry(16, "塔 (The Tower)"),
        Map.entry(17, "星星 (The Star)"),
        Map.entry(18, "月亮 (The Moon)"),
        Map.entry(19, "太阳 (The Sun)"),
        Map.entry(20, "审判 (Judgement)"),
        Map.entry(21, "世界 (The World)")
    );

    // 完整的78张塔罗牌堆（22张大阿尔克那 + 56张小阿尔克那）
    private static final List<String> FULL_DECK;
    
    static {
        List<String> deck = new ArrayList<>(78);
        
        // 添加22张大阿尔克那
        deck.addAll(MAJOR_ARCANA.values());
        
        // 添加56张小阿尔克那
        String[] suits = {"权杖 (Wands)", "圣杯 (Cups)", "宝剑 (Swords)", "星币 (Pentacles)"};
        String[] ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
                         "侍从 (Page)", "骑士 (Knight)", "皇后 (Queen)", "国王 (King)"};
        
        for (String suit : suits) {
            for (String rank : ranks) {
                deck.add(rank + " - " + suit);
            }
        }
        
        FULL_DECK = Collections.unmodifiableList(deck);
    }

    // 占卜类型
    private static final Map<String, String> DIVINATION_TYPES = Map.of(
        "单牌", "单张牌占卜，适合简单问题",
        "三牌阵", "过去-现在-未来牌阵，适合时间线分析",
        "凯尔特十字", "十张牌综合分析，适合复杂问题",
        "关系牌阵", "专门分析感情关系",
        "决策牌阵", "帮助做出重要决定"
    );

    @Tool(description = """
            抽取塔罗牌进行占卜。根据用户的问题类型和需求，选择合适的牌阵进行抽牌。
            支持单牌占卜、三牌阵、凯尔特十字等多种牌阵。
            注意：每个会话只能抽牌一次，后续应基于已有牌面回答问题。
            """)
    public String drawTarotCards(
            @ToolParam(description = "占卜问题或咨询内容") String question,
            @ToolParam(description = "牌阵类型：单牌、三牌阵、凯尔特十字、关系牌阵、决策牌阵") String spreadType,
            @ToolParam(description = "抽牌数量，默认根据牌阵类型决定") Integer cardCount
    ) {
        log.info("塔罗占卜 - 问题: {}, 牌阵: {}, 数量: {}", question, spreadType, cardCount);
        
        // 新增：检测用户是否提出“重抽/重新抽卡”需求，给出新一轮会话建议与抽牌方式选择
        String _q = question == null ? "" : question;
        String _s = spreadType == null ? "" : spreadType;
        if (_q.contains("重抽") || _q.contains("再抽") || _q.contains("重新抽") || _q.contains("重新开始") || _s.contains("重抽")) {
            return """
                    needConfirm=true
                    
                    你希望重新抽牌。建议以全新能量开启新一轮对话：
                    
                    · 方式一：发送“确认重开”，我将结束本轮并在新会话为你抽牌。
                    · 方式二：你直接发出新一轮的首条消息（写明你的问题 + 想用的牌阵/张数）。
                    
                    同时，请先选择抽牌方式：
                    1) 你来自选（请给出每张牌名与正/逆位，例如：Two of Cups 逆位）
                    2) 我来代抽（默认随机且公平）
                    
                    请选择你的方式，并告知是否要立即重开。
                    """;
        }
         
         // 情况1：参数不明确 - 需要澄清
         if (spreadType == null || spreadType.trim().isEmpty() || 
             spreadType.contains("不确定") || spreadType.contains("随意") ||
             spreadType.contains("任意") || spreadType.contains("看着办")) {
             return """
                     needConfirm=true
                     
                     请先选择抽牌方式：
                     1) 你来自选（请给出每张牌名与正/逆位，例如：Two of Cups 逆位）
                     2) 我来代抽（默认随机且公平）
                     
                     接着，选择适合的牌阵类型：
                     
                     🔮 **推荐牌阵**：
                     1️⃣ **单牌** - 日运指引、简要建议
                     2️⃣ **三牌阵** - 过去现在未来分析  
                     3️⃣ **凯尔特十字** - 复杂问题深度解析
                     4️⃣ **关系牌阵** - 感情关系问题
                     5️⃣ **决策牌阵** - 选择决策问题
                     
                     请告诉我你想用哪种牌阵？
                     """;
         }
    
         // 情况2：正常抽牌逻辑
         int finalCardCount = determineCardCount(spreadType, cardCount);
         List<TarotCard> drawnCards = drawRandomCards(finalCardCount);
         
         StringBuilder result = new StringBuilder();
         result.append("🔮 **塔罗占卜结果** 🔮\n\n");
         result.append("📝 **问题**：").append(question).append("\n");
         result.append("🎴 **牌阵**：").append(spreadType).append("\n");
         result.append("⏰ **抽牌时间**：").append(new Date()).append("\n\n");
         
         // 根据不同牌阵格式化结果
         switch (spreadType) {
             case "单牌":
                 result.append(formatSingleCard(drawnCards.get(0)));
                 break;
             case "三牌阵":
                 result.append(formatThreeCardSpread(drawnCards));
                 break;
             case "凯尔特十字":
                 result.append(formatCelticCross(drawnCards));
                 break;
             case "关系牌阵":
                 result.append(formatRelationshipSpread(drawnCards));
                 break;
             case "决策牌阵":
                 result.append(formatDecisionSpread(drawnCards));
                 break;
             default:
                 result.append(formatGeneralSpread(drawnCards));
         }
         
         result.append("\n 建议：请结合具体牌义进行深度解读，关注牌面间的相互关系和整体能量流向。");
         
         return result.toString();
     }
    @Tool(description = """
            查询特定塔罗牌的详细牌义解释。可以查询正位或逆位含义，
            以及在学业、事业、感情等不同领域的具体解读。
            """)
    public String getTarotCardMeaning(
            @ToolParam(description = "塔罗牌名称或编号，如'愚者'、'0'、'The Fool'") String cardName,
            @ToolParam(description = "牌位方向：正位或逆位") String position,
            @ToolParam(description = "查询领域：学业、事业、感情，可选") String domain
    ) {
        log.info("查询塔罗牌义 - 牌名: {}, 方向: {}, 领域: {}", cardName, position, domain);
        
        // 标准化牌名
        String standardCardName = standardizeCardName(cardName);
        if (standardCardName == null) {
            return "未找到对应的塔罗牌，请检查牌名是否正确。支持中文名、英文名或编号。";
        }
       
        StringBuilder result = new StringBuilder();
        result.append(standardCardName).append(" 牌义解读\n\n");
        result.append("方向：").append(position).append("\n\n");
        
        // 这里返回基础信息，让RAG系统进行详细检索
        result.append("请查询RAG知识库获取 ").append(standardCardName)
               .append(" 的").append(position).append("含义");
        
        if (domain != null && !domain.isEmpty()) {
            result.append("，特别关注").append(domain).append("方面的解读");
        }
        
        result.append("。\n\n");
        result.append(" 检索关键词：").append(standardCardName).append(" ").append(position);
        
        return result.toString();
    }

    @Tool(description = """
            生成完整的塔罗占卜分析报告。整合牌阵信息、牌义解读和综合建议，
            提供专业的占卜咨询服务。
            """)
    public String generateTarotReading(
            @ToolParam(description = "抽牌结果信息") String cardInfo,
            @ToolParam(description = "占卜问题") String question,
            @ToolParam(description = "咨询者的背景信息，可选") String background
    ) {
        log.info("生成塔罗占卜报告 - 问题: {}", question);
        
        StringBuilder analysis = new StringBuilder();
        analysis.append(" 塔罗占卜深度分析报告\n\n");
        analysis.append("═══════════════════════════\n\n");
        
        analysis.append(" 咨询问题：\n").append(question).append("\n\n");
        
        if (background != null && !background.isEmpty()) {
            analysis.append(" 背景信息：\n").append(background).append("\n\n");
        }
        
        analysis.append(" 抽牌结果：\n").append(cardInfo).append("\n\n");
        
        analysis.append(" 综合解读指引：\n");
        analysis.append("1. 请结合牌面的正逆位含义进行基础解读\n");
        analysis.append("2. 分析牌与牌之间的能量关系和互动影响\n");
        analysis.append("3. 根据问题类型重点关注相应的解读维度\n");
        analysis.append("4. 提供具体可行的建议和行动方向\n");
        analysis.append("5. 给出时间预测和注意事项\n\n");
        analysis.append(" 解读要点：\n");
        analysis.append("• 关注牌面的象征意义和深层启示\n");
        analysis.append("• 结合咨询者的实际情况给出贴合的建议\n");
        analysis.append("• 保持积极正面的引导态度\n");
        analysis.append("• 强调个人选择的重要性和能动作用\n\n");
        
        analysis.append("请基于以上信息进行详细的塔罗占卜解读。");
        
        return analysis.toString();
    }

     @Tool(description = """
             列出可用的塔罗牌阵类型和说明，帮助用户选择合适的牌阵。
             """)
     public String listAvailableSpreads() {
         return """
                 🔮 **可用塔罗牌阵**：
                 
                  **单牌占卜**
                    - 适合：日运、简要指引、快速建议
                    - 牌数：1张
                 
                  **三牌阵（过去-现在-未来）**
                    - 适合：时间线分析、发展趋势
                    - 牌数：3张
                 
                  **凯尔特十字**
                    - 适合：复杂问题、深度分析
                    - 牌数：10张
                    
                  **关系牌阵**
                    - 适合：感情关系、人际问题
                    - 牌数：5张
                    
                  **决策牌阵**
                    - 适合：选择困难、重要决定
                    - 牌数：4张
                 
                 请告诉我你想用哪种牌阵进行占卜？
                 """;
     }


 
    private int determineCardCount(String spreadType, Integer cardCount) {
        if (cardCount != null && cardCount > 0) {
            return Math.min(cardCount, 10); // 最多10张牌
        }
        
        return switch (spreadType) {
            case "单牌" -> 1;
            case "三牌阵" -> 3;
            case "凯尔特十字" -> 10;
            case "关系牌阵" -> 5;
            case "决策牌阵" -> 4;
            default -> 3;
        };
    }

    private List<TarotCard> drawRandomCards(int count) {
        // 从完整牌堆中无放回抽取 count 张
        List<String> pool = new ArrayList<>(FULL_DECK);
        Collections.shuffle(pool);
        int realCount = Math.min(count, pool.size());
        List<TarotCard> cards = new ArrayList<>(realCount);
        for (int i = 0; i < realCount; i++) {
            String name = pool.get(i);
            boolean isReversed = RandomUtil.randomBoolean();
            // 对于大阿尔克那保留编号，否则用 -1 表示非大阿尔克那
            int number = MAJOR_ARCANA.entrySet().stream()
                    .filter(e -> e.getValue().equals(name))
                    .map(Map.Entry::getKey)
                    .findFirst()
                    .orElse(-1);
            cards.add(new TarotCard(number, name, isReversed));
        }
        return cards;
    }

    private String formatSingleCard(TarotCard card) {
        return String.format(" 抽取牌：%s (%s)\n位置：%s\n\n这张牌为您当前的问题提供了直接的指引。", 
                card.getName(), card.getNumber(), card.isReversed() ? "逆位" : "正位");
    }

    private String formatThreeCardSpread(List<TarotCard> cards) {
        StringBuilder sb = new StringBuilder();
        sb.append(" 三牌阵布局：\n\n");
        sb.append("过去：").append(cards.get(0).getName()).append(" (").append(cards.get(0).isReversed() ? "逆位" : "正位").append(")\n");
        sb.append("现在：").append(cards.get(1).getName()).append(" (").append(cards.get(1).isReversed() ? "逆位" : "正位").append(")\n");
        sb.append("未来：").append(cards.get(2).getName()).append(" (").append(cards.get(2).isReversed() ? "逆位" : "正位").append(")\n\n");
        sb.append("这个牌阵揭示了您问题的时间线发展脉络。");
        return sb.toString();
    }

    private String formatCelticCross(List<TarotCard> cards) {
        StringBuilder sb = new StringBuilder();
        sb.append(" 凯尔特十字牌阵：\n\n");
        String[] positions = {"当前状况", "挑战/阻碍", "远程过去", "近期过去", "可能未来", "近期未来", "您的态度", "外界影响", "希望与恐惧", "最终结果"};
        
        for (int i = 0; i < Math.min(cards.size(), 10); i++) {
            sb.append(String.format("%d. %s：%s (%s)\n", i+1, positions[i], 
                    cards.get(i).getName(), cards.get(i).isReversed() ? "逆位" : "正位"));
        }
        
        sb.append("\n这是最全面的塔罗牌阵，为您的问题提供360度的深度分析。");
        return sb.toString();
    }

    private String formatRelationshipSpread(List<TarotCard> cards) {
        StringBuilder sb = new StringBuilder();
        sb.append(" 关系牌阵：\n\n");
        String[] positions = {"您的感受", "对方的感受", "关系现状", "阻碍因素", "发展方向"};
        
        for (int i = 0; i < Math.min(cards.size(), 5); i++) {
            sb.append(String.format("%s：%s (%s)\n", positions[i], 
                    cards.get(i).getName(), cards.get(i).isReversed() ? "逆位" : "正位"));
        }
        
        sb.append("\n专门针对感情关系设计的牌阵，帮助您理解关系的各个层面。");
        return sb.toString();
    }

    private String formatDecisionSpread(List<TarotCard> cards) {
        StringBuilder sb = new StringBuilder();
        sb.append(" 决策牌阵：\n\n");
        String[] positions = {"现状分析", "选择A的结果", "选择B的结果", "最佳建议"};
        
        for (int i = 0; i < Math.min(cards.size(), 4); i++) {
            sb.append(String.format("%s：%s (%s)\n", positions[i], 
                    cards.get(i).getName(), cards.get(i).isReversed() ? "逆位" : "正位"));
        }
        
        sb.append("\n帮助您在重要决策时获得明确的指引和建议。");
        return sb.toString();
    }

    private String formatGeneralSpread(List<TarotCard> cards) {
        StringBuilder sb = new StringBuilder();
        sb.append(" 抽取的塔罗牌：\n\n");
        
        for (int i = 0; i < cards.size(); i++) {
            sb.append(String.format("%d. %s (%s)\n", i+1, 
                    cards.get(i).getName(), cards.get(i).isReversed() ? "逆位" : "正位"));
        }
        
        return sb.toString();
    }

    private String standardizeCardName(String cardName) {
        // 尝试按编号查找
            int number = Integer.parseInt(cardName);
            return FULL_DECK.get(number);
    }

    // 内部类：塔罗牌对象
    private static class TarotCard {
        private final int number;
        private final String name;
        private final boolean reversed;

        public TarotCard(int number, String name, boolean reversed) {
            this.number = number;
            this.name = name;
            this.reversed = reversed;
        }

        public int getNumber() { return number; }
        public String getName() { return name; }
        public boolean isReversed() { return reversed; }
    }

    @Tool(description = """
            用户自选塔罗牌进行占卜。用户直接指定牌名与正逆位，无需系统随机抽取。
            适用于用户希望自主控制牌面的场景。
            """)
    public String drawUserSelectedCards(
            @ToolParam(description = "占卜问题或咨询内容") String question,
            @ToolParam(description = "牌阵类型：单牌、三牌阵、凯尔特十字、关系牌阵、决策牌阵") String spreadType,
            @ToolParam(description = "用户选择的牌名列表，格式：牌名1-正位/逆位,牌名2-正位/逆位") String selectedCards
    ) {
        log.info("用户自选塔罗占卜 - 问题: {}, 牌阵: {}, 选牌: {}", question, spreadType, selectedCards);

        if (selectedCards == null || selectedCards.trim().isEmpty()) {
            return """
                    needConfirm=true
                    
                    请告诉我你选择的具体牌名与正逆位，格式例如：
                    · 单牌：Two of Cups 逆位
                    · 三牌阵：愚者 正位, 恋人 逆位, 星星 正位
                    · 多牌：The Fool-正位,The Lovers-逆位,The Star-正位
                    
                    支持中文名（愚者）、英文名（The Fool）或编号（0）。
                    """;
        }

        // 解析用户选择的牌
        List<TarotCard> userCards = parseUserSelectedCards(selectedCards);
        if (userCards.isEmpty()) {
            return "抱歉，无法解析你选择的牌名。请使用正确格式，如：愚者 正位, 恋人 逆位";
        }

        StringBuilder result = new StringBuilder();
        result.append("🔮 **用户自选塔罗占卜结果** 🔮\n\n");
        result.append("📝 **问题**：").append(question).append("\n");
        result.append("🎴 **牌阵**：").append(spreadType).append("\n");
        result.append("👤 **选牌方式**：用户自选\n");
        result.append("⏰ **占卜时间**：").append(new Date()).append("\n\n");

        // 根据不同牌阵格式化结果
        switch (spreadType) {
            case "单牌":
                if (userCards.size() >= 1) {
                    result.append(formatSingleCard(userCards.get(0)));
                }
                break;
            case "三牌阵":
                if (userCards.size() >= 3) {
                    result.append(formatThreeCardSpread(userCards.subList(0, 3)));
                } else {
                    result.append(formatGeneralSpread(userCards));
                }
                break;
            case "凯尔特十字":
                if (userCards.size() >= 10) {
                    result.append(formatCelticCross(userCards.subList(0, 10)));
                } else {
                    result.append(formatGeneralSpread(userCards));
                }
                break;
            case "关系牌阵":
                if (userCards.size() >= 5) {
                    result.append(formatRelationshipSpread(userCards.subList(0, 5)));
                } else {
                    result.append(formatGeneralSpread(userCards));
                }
                break;
            case "决策牌阵":
                if (userCards.size() >= 4) {
                    result.append(formatDecisionSpread(userCards.subList(0, 4)));
                } else {
                    result.append(formatGeneralSpread(userCards));
                }
                break;
            default:
                result.append(formatGeneralSpread(userCards));
        }

        result.append("\n✨ 备注：基于你的直觉选择，牌面将反映你当前的内心状态与潜意识指引。");

        return result.toString();
    }

    /**
     * 解析用户选择的牌名与正逆位
     */
    private List<TarotCard> parseUserSelectedCards(String selectedCards) {
        List<TarotCard> cards = new ArrayList<>();

        // 支持多种分隔符：逗号、分号、换行
        String[] cardStrings = selectedCards.split("[,;\\n]+");

        for (String cardString : cardStrings) {
            cardString = cardString.trim();
            if (cardString.isEmpty()) continue;

            // 解析牌名与正逆位
            String cardName = "";
            boolean reversed = false;

            // 格式1：牌名-正位/逆位
            if (cardString.contains("-")) {
                String[] parts = cardString.split("-", 2);
                cardName = parts[0].trim();
                if (parts.length > 1) {
                    String position = parts[1].trim();
                    reversed = position.contains("逆") || position.toLowerCase().contains("reversed");
                }
            }
            // 格式2：牌名 正位/逆位 (空格分隔)
            else if (cardString.contains(" ")) {
                String[] parts = cardString.split("\\s+");
                if (parts.length >= 2) {
                    // 最后一个词是方向，前面都是牌名
                    String position = parts[parts.length - 1];
                    reversed = position.contains("逆") || position.toLowerCase().contains("reversed");
                    cardName = String.join(" ", Arrays.copyOf(parts, parts.length - 1));
                } else {
                    cardName = cardString;
                }
            }
            // 格式3：只有牌名，默认正位
            else {
                cardName = cardString;
            }

            // 标准化牌名
            String standardName = standardizeCardName(cardName);
            if (standardName != null) {
                // 为用户自选牌分配一个索引号（基于在FULL_DECK中的位置）
                int cardIndex = FULL_DECK.indexOf(standardName);
                if (cardIndex == -1) {
                    // 如果在FULL_DECK中找不到，尝试在MAJOR_ARCANA中查找
                    for (Map.Entry<Integer, String> entry : MAJOR_ARCANA.entrySet()) {
                        if (entry.getValue().equals(standardName)) {
                            cardIndex = entry.getKey();
                            break;
                        }
                    }
                }
                cards.add(new TarotCard(cardIndex >= 0 ? cardIndex : 0, standardName, reversed));
            }
        }

        return cards;
    }
}